package initialization

import (
	"fmt"
	"gitee.com/danlansky/go-library/utils"
	"github.com/spf13/viper"
	"log"
	"os"
)

const (
	defaultConfigPath        = "/config/"
	defaultConfigType        = ".toml"
	defaultConfigFileNamePre = "config-"
	baseConfigTag            = "app"
)

// app配置信息
type appConfig struct {
	Name   string          `mapstructure:"name"`
	Desc   string          `mapstructure:"desc"`
	Env    string          `mapstructure:"env"`
	Module string          `mapstructure:"module"`
	Server appConfigServer `mapstructure:"server"`
	Log    appConfigLog    `mapstructure:"log"`
}

type appConfigServer struct {
	Port string `mapstructure:"port"`
}

type appConfigLog struct {
	RootPath         string `mapstructure:"root_path"`
	LocalIP          string `mapstructure:"local_ip"`
	MaxRetentionDays int    `mapstructure:"max_retention_days"`
	IsLevel          bool   `mapstructure:"is_level"`
	StdOut           bool   `mapstructure:"std_out"`
}

var configPath string

// 初始化配置文件
func initConfig(env string, module string) *appConfig {
	//interface{} 类型可以被任何类型赋值，但是go 1.18 interface{} 不可以直接给其他类型赋值
	rootPath, err := os.Getwd()
	if err != nil {
		log.Println("init config: Failed to get rootPath directory.")
		panic(err)
	}

	configPath = rootPath + defaultConfigPath
	//1.读取公共example.toml配置文件
	confFile := fmt.Sprintf("%s%s%s%s", configPath, defaultConfigFileNamePre, env, defaultConfigType)
	if !utils.FileIsExist(confFile) {
		errMsg := fmt.Sprintf("init config: (%s)Config file does not exist.", confFile)
		log.Println("cmd example: ./name -c=test -p=xxx")
		panic(errMsg)
	}
	//viper.SetConfigName(c.Env) //设置文件名时不要带后缀
	//viper.SetConfigType(c.ConfType)
	//viper.AddConfigPath(c.ConfPath) //搜索路径可以设置多个，viper 会根据设置顺序依次查找
	viper.SetConfigFile(confFile)
	viper.AutomaticEnv() // 读取匹配的环境变量
	err = viper.MergeInConfig()
	if err != nil {
		log.Fatalf("read config[%s] failed", confFile)
		panic(err)
	}

	// 合并项目配置文件 MergeInConfig
	if module != "" {
		projectConfFile := fmt.Sprintf("%s%s/%s%s%s", configPath, module, defaultConfigFileNamePre, env, defaultConfigType)
		if utils.FileIsExist(projectConfFile) {
			viper.SetConfigFile(projectConfFile)
			if err2 := viper.MergeInConfig(); err2 != nil {
				log.Fatalf("read project config[%s] failed: %v", confFile, err2)
			}
		}
	}
	baseConfig := &appConfig{}
	_ = viper.UnmarshalKey(baseConfigTag, baseConfig)
	if baseConfig.Name == "" || baseConfig.Desc == "" || baseConfig.Env == "" {
		errMsg := "app config error"
		panic(errMsg)
	}
	baseConfig.Module = module
	// 获取ip
	if baseConfig.Log.LocalIP == "" {
		baseConfig.Log.LocalIP = utils.GetIp()
	}
	return baseConfig
}
